using UnityEngine;
using System;
using Object = UnityEngine.Object;

namespace Framework
{
    public interface IGameObjectPool { }

    public class GameObjectPool<T> : IGameObjectPool, IObjectPool<T> where T : Object
    {
        private readonly ObjectPool<T> pool;
        
        private T prefab;
        private Transform root;
        private bool resetParentOnRelease;

        public GameObjectPool(T prefab, Transform root, bool resetParentOnRelease=true, Action<T> OnHandled=null)
        {
            this.prefab = prefab;
            this.root = root;
            this.resetParentOnRelease = resetParentOnRelease;
            pool = new ObjectPool<T>(Create, OnActivate, OnRelease, OnHandled, OnDestroy);
        }
        
        private T Create() => Object.Instantiate(prefab, root);

        private void OnActivate(T obj)
        {
            switch (obj)
            {
                case GameObject go:
                    go.SetActive(true);
                    break;
                case Component c:
                    c.gameObject.SetActive(true);
                    break;
            }
        }

        private void OnRelease(T obj)
        {
            switch (obj)
            {
                case GameObject go: 
                    go.SetActive(false);
                    if (resetParentOnRelease) go.transform.SetParent(root);
                    break;
                case Component c:
                    c.gameObject.SetActive(false);
                    if (resetParentOnRelease) c.transform.SetParent(root);
                    break;
            }
        }

        private void OnDestroy(T obj)
        {
            switch (obj)
            {
                case GameObject go:
                    Object.Destroy(go);
                    break;
                case Component c:
                    Object.Destroy(c.gameObject);
                    break;
            }
        }

        public T Get() => pool.Get();
        public void Release(T obj) => pool.Release(obj);
    }
}